gtk3: add randr 1.5 monitor support
authorDave Airlie <airlied@redhat.com>
Mon, 2 Feb 2015 06:02:04 +0000 (16:02 +1000)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 22 May 2015 03:09:04 +0000 (23:09 -0400)
This patch introduces support for using the newly introduced
monitor objects in the XRandR protocol. These objects are meant
to be used to denote a set of rectangles representing a logical
monitor, and are used to hide details like monitor tiling and
virtual gpu outputs.

This uses the new objects instead of crtc/outputs objects when
they are available to create the monitor lists. X server 1.18
is required on the server side for randr 1.5.

https://bugzilla.gnome.org/show_bug.cgi?id=749561

configure.ac
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkdisplay-x11.h
gdk/x11/gdkscreen-x11.c

index 1f3185044f6dd0ee50343b3c64ca00b9e9b562c1..106ff8ff347abce9b30af25410ecf3d4d8613a76 100644 (file)
@@ -1184,6 +1184,9 @@ if test "x$enable_x11_backend" = xyes; then
     if $PKG_CONFIG --exists "xrandr >= 1.2.99" ; then
       AC_DEFINE(HAVE_RANDR, 1, [Have the Xrandr extension library])
 
+      if $PKG_CONFIG --exists "xrandr >= 1.5.0" ; then
+        AC_DEFINE(HAVE_RANDR15, 1, [Have the Xrandr 1.5 extension library])
+      fi
       X_PACKAGES="$X_PACKAGES xrandr"
       X_EXTENSIONS="$X_EXTENSIONS XRANDR"
     elif test x"$enable_xrandr" = xyes; then
index 1477a75d8b231ebcf75039a40c1b75e1942a033b..d4be951bb036d62edfe966b0cf040c4cfa12d3dd 100644 (file)
@@ -1397,6 +1397,7 @@ _gdk_x11_display_open (const gchar *display_name)
   /* RandR must be initialized before we initialize the screens */
   display_x11->have_randr12 = FALSE;
   display_x11->have_randr13 = FALSE;
+  display_x11->have_randr15 = FALSE;
 #ifdef HAVE_RANDR
   if (XRRQueryExtension (display_x11->xdisplay,
                         &display_x11->xrandr_event_base, &ignore))
@@ -1409,6 +1410,10 @@ _gdk_x11_display_open (const gchar *display_name)
          display_x11->have_randr12 = TRUE;
          if (minor >= 3 || major > 1)
              display_x11->have_randr13 = TRUE;
+#ifdef HAVE_RANDR15
+         if (minor >= 5 || major > 1)
+             display_x11->have_randr15 = TRUE;
+#endif
       }
 
        gdk_x11_register_standard_event_type (display, display_x11->xrandr_event_base, RRNumberEvents);
index f601ed376368337adf7f9f4d444709736472d9e1..b0c49a08586eded11efb5975686f67a2687c29a9 100644 (file)
@@ -66,6 +66,7 @@ struct _GdkX11Display
 
   gboolean have_randr12;
   gboolean have_randr13;
+  gboolean have_randr15;
   gint xrandr_event_base;
 
   /* If the SECURITY extension is in place, whether this client holds
index 5c71c538a7791e43bd16c1682a6205309c27398d..a1d0a7c95464d4c3cc58eeb381f65e51d192f646 100644 (file)
@@ -613,6 +613,59 @@ monitor_compare_function (GdkX11Monitor *monitor1,
 }
 #endif
 
+#ifdef HAVE_RANDR15
+static gboolean
+init_randr15 (GdkScreen *screen)
+{
+  GdkDisplay *display = gdk_screen_get_display (screen);
+  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+  GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
+  XRRMonitorInfo *rr_monitors;
+  int num_rr_monitors;
+  int i;
+  GArray *monitors;
+  int primary_idx = 0;
+
+  if (!display_x11->have_randr15)
+    return FALSE;
+
+  rr_monitors = XRRGetMonitors (x11_screen->xdisplay,
+                                x11_screen->xroot_window,
+                                True,
+                                &num_rr_monitors);
+  if (!rr_monitors)
+    return FALSE;
+
+  monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor),
+                                num_rr_monitors);
+  for (i = 0; i < num_rr_monitors; i++)
+    {
+      GdkX11Monitor monitor;
+      init_monitor_geometry (&monitor,
+                             rr_monitors[i].x,
+                             rr_monitors[i].y,
+                             rr_monitors[i].width,
+                             rr_monitors[i].height);
+
+      monitor.width_mm = rr_monitors[i].mwidth;
+      monitor.height_mm = rr_monitors[i].mheight;
+      monitor.output = rr_monitors[i].outputs[0];
+      if (rr_monitors[i].primary)
+        primary_idx = i;
+      g_array_append_val (monitors, monitor);
+    }
+  XRRFreeMonitors (rr_monitors);
+
+  g_array_sort (monitors,
+                (GCompareFunc) monitor_compare_function);
+  x11_screen->n_monitors = monitors->len;
+  x11_screen->monitors = (GdkX11Monitor *) g_array_free (monitors, FALSE);
+
+  x11_screen->primary_monitor = primary_idx;
+  return x11_screen->n_monitors > 0;
+}
+#endif
+
 static gboolean
 init_randr13 (GdkScreen *screen)
 {
@@ -1060,6 +1113,11 @@ init_multihead (GdkScreen *screen)
   if (init_fake_xinerama (screen))
     return;
 
+#ifdef HAVE_RANDR15
+  if (init_randr15 (screen))
+    return;
+#endif
+
   if (init_randr13 (screen))
     return;